#include <iostream>

using namespace std;

class A
{
  public:
    virtual void f(){}
    int _a;
};

class B : public A
{
  public:
    int _b;
};

void fun(A *pa)
{
    B *ptr = dynamic_cast<B*>(pa);
    if(ptr != nullptr)
    {
        ptr->_a = 10;
        cout << ptr << endl;
    }
    else 
    {
        cout << "转换失败" << endl;
    }
}

int main()
{
    A a;
    B b;
    fun(&a);
    fun(&b);
    return 0;
}



// int main()
// {
    // double d = 12.34;
    // int a = static_cast<int>(d);
    // cout << a << endl;

    // long i = 0;
    // long *p = &i;
    // long address = reinterpret_cast<long>(p);
    // cout << address << endl;

    // volatile const int a = 2;
    // int *p = const_cast<int*>(&a);
    // *p = 3;

    // cout << a << endl;
    // cout << *p << endl;

//     return 0;
// }

// #include <iostream>
// #include <string>
// #include <thread>
// #include <mutex>
// using namespace std;

// #include "SmartPtr.h"

// struct Date
// {
//     int _year = 1;
//     int _month = 1;
//     int _day = 1;
// };

// void SharedPtrFunc(SharePtr<Date>& sp, size_t n)
// {
//     // cout << sp.get() << endl;
//     for(size_t i = 0; i < n; i++)
//     {
//         SharePtr<Date> copy(sp);    //修改引用计数
//         //修改智能指针所指向的内容
//         copy->_year++;
//         copy->_month++;
//         copy->_day++;
//     }
// }

// void testSharedPtrThreadSafe()
// {
//     SharePtr<Date> p(new Date);
//     cout << p.get() << endl;
//     cout << p.use_count() << endl;

//     const size_t n = 1000000;
//     thread t1(SharedPtrFunc, ref(p), n);
//     thread t2(SharedPtrFunc, ref(p), n);

//     t1.join();
//     t2.join();

//     cout << p.get() << endl;
//     cout << p.use_count() << endl;

//     cout << p->_year << endl;
//     cout << p->_month << endl;
//     cout << p->_day << endl;

// }

// struct ListNode
// {
//     ~ListNode()
//     {
//         cout << "~ListNode" << endl;
//     }
//     // ListNode *_prev;
//     // ListNode *_next;
//     // SharePtr<ListNode> _prev;
//     // SharePtr<ListNode> _next;
//     // std::weak_ptr<ListNode> _prev;
//     // std::weak_ptr<ListNode> _next;
//     WeakPtr<ListNode> _prev;
//     WeakPtr<ListNode> _next;
//     int val;
// };
//循环引用
// void test_cycle_ref()
// {
//     // std::shared_ptr<ListNode> n1(new ListNode);
//     // std::shared_ptr<ListNode> n2(new ListNode);
//     SharePtr<ListNode> n1(new ListNode);
//     SharePtr<ListNode> n2(new ListNode);
    
//     n1->_next = n2;
//     n2->_prev = n1;
//     cout << n1.use_count() << endl;
//     cout << n2.use_count() << endl;

//     WeakPtr<ListNode> cur = n1;
//     while(cur.get() != nullptr)
//     {
//         cout << cur->val << " ";
//         cur = cur->_next;
//     }
//     cout << endl;
//     // n1->_next = n2.get();
//     // std::shared_ptr<ListNode> n3 = new ListNode;
//     // ListNode *n1 = new ListNode;
//     // ListNode *n2 = new ListNode;
//     // n1.get()->_next = n2.get();
//     // n2.get()->_prev = n1.get();
//     // n1->_next = n2;
//     // n2->_prev = n1;
    
//     //此处可能会抛异常
//     // delete n1;
//     // delete n2;
// }

// int main()
// {
//     test_cycle_ref();
//     return 0;
// }

// mutex mtx;

// void func(int &val)
// {
//     mtx.lock();
//     val++;
//     mtx.unlock();
// }

// int main()
// {
//     int val = 0;
//     thread t1(func, ref(val));
//     thread t2(func, ref(val));
//     cout << val << endl;
//     t1.join();
//     t2.join();
//     cout << val << endl;
// }

// int main()
// {
//     // SharePtr<int> sp1(new int);
//     // SharePtr<int> sp2(sp1);
//     // SharePtr<int> sp3(new int);
//     // sp3 = sp2;

//     testSharedPtrThreadSafe();
//     return 0;
// }

// int main()
// {
//     /*拷贝构造测试*/
//     UniquePtr<int> up1(new int);
//     UniquePtr<int> up2(up1);
//     /*赋值重载测试*/
//     UniquePtr<int> up3(new int);
//     up2 = up3;
//     return 0;
// }

// double div()
// {
//     double a, b;
//     cin >> a >> b;
//     if(b == 0)
//     {
//         __throw_invalid_argument("除0错误");
//     }
//     return a / b;
// }

// void f1()
// {
//     /* int *p = new int;
//     SmartPtr<int> sp(p); */
//     SmartPtr<int> sp(new int);
//     cout << div() << endl;
// }

// int main()
// {
//     try{
//         f1();
//     }
//     catch (exception &e)
//     {
//         cout << e.what() << endl;
//     }
//     return 0;
// }


//
//class Exception
//{
//public:
//	Exception(int errid, const string& errmsg)
//		:_errid(errid)
//		, _errmsg(errmsg)
//	{}
//
//	const string& what() const
//	{
//		return _errmsg;
//	}
//
//private:
//	int _errid;
//	string _errmsg;
//	// ...
//	//stack<Info> _stInfo;
//};
//
////void File()
////{
////	string file;
////	cin >> file;
////	FILE* fout = fopen(file.c_str(), "r");
////	if (fout == nullptr)
////	{
////		throw  errno;
////	}
////
////	char ch;
////	while ((ch = fgetc(fout)) != EOF)
////	{
////		cout << ch;
////	}
////
////	//..
////	fclose(fout);
////}
////
////double Division(int a, int b)
////{
////	// 当b == 0时抛出异常
////	if (b == 0)
////		throw "Division by zero condition!";
////	else
////		return ((double)a / (double)b);
////}
////
////void Func()
////{
////	int len, time;
////	cin >> len >> time;
////	try
////	{
////		cout << Division(len, time) << endl;
////	}
////	catch(const char* errmsg)
////	{
////		cout << errmsg << endl;
////	}
////
////	File();
////}
////
////int main()
////{
////	try {
////		Func();
////	}
////	catch (const char* errmsg)
////	{
////		cout << errmsg << endl;
////	}
////	catch (int errid)
////	{
////		cout << errid << endl;
////	}
////
////	return 0;
////}
//
//
//void File()
//{
//	string file;
//	cin >> file;
//	FILE* fout = fopen(file.c_str(), "r");
//	if (fout == nullptr)
//	{
//		string errmsg = "打开文件失败：";
//		errmsg += file;
//		errmsg += "->";
//		errmsg += strerror(errno);
//		Exception e(errno, errmsg);
//		throw e;
//	}
//
//	char ch;
//	while ((ch = fgetc(fout)) != EOF)
//	{
//		cout << ch;
//	}
//
//	//..
//	fclose(fout);
//}
//
//double Division(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		string errmsg = "Division by zero condition!";
//		Exception e(100, errmsg);
//		throw e;
//	}
//	else
//	{
//		return ((double)a / (double)b);
//	}
//}
//
//void Func()
//{
//	//mtx.lock();
//	//std::lock_guard<mutex> lock(mtx);
//	int* p = new int[100]; // -> 智能指针
//	int len, time;
//	cin >> len >> time;
//	try {
//		cout << Division(len, time) << endl;
//		File();
//	}
//	catch (...)
//	{
//		// 捕获以后，不是要处理异常，异常由最外层统一处理
//		// 这里捕获异常，只是为了处理掉内存泄漏的问题
//		delete[] p;
//		//mtx.unlock();
//
//		throw; // 捕获到什么，就继续抛出什么
//	}
//
//	delete[] p;
//	//mtx.unlock();
//}
//
//int main()
//{
//	try {
//		Func();
//	}
//	catch (const Exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...) // 捕获任意类型异常
//	{
//		cout << "未知异常" << endl;
//	}
//
//	return 0;
//}

// 服务器开发中通常使用的异常继承体系
// class Exception
// {
// public:
// 	Exception(int errid, const char* errmsg)
// 		: _errid(errid)
// 		, _errmsg(errmsg)
// 	{}

// 	virtual string what() const
// 	{
// 		return _errmsg;
// 	}
// protected:
// 	string _errmsg;
// 	int _errid;
// };

// class SqlException : public Exception
// {
// public:
// 	SqlException(int errid, const char* errmsg, const char* sql = "")
// 		:Exception(errid, errmsg)
// 		, _sql(sql)
// 	{}

// 	virtual string what() const
// 	{
// 		string msg = "SqlException:";
// 		msg += _errmsg;
// 		msg += " sql:";
// 		msg += _sql;
		
// 		return msg;
// 	}
// private:
// 	string _sql;
// };

// class CacheException : public Exception
// {
// public:
// 	CacheException(int errid, const char* errmsg)
// 		:Exception(errid, errmsg)
// 	{}

// 	virtual string what() const
// 	{
// 		string msg = "CacheException:";
// 		msg += _errmsg;

// 		return msg;
// 	}
// };

// void f1()
// {
// 	// ....
// 	int i;
// 	cin >> i;
// 	if (i == 0)
// 	{
// 		throw CacheException(1, "数据不存在");
// 	}
// }

// void f2()
// {
// 	int i;
// 	cin >> i;
// 	if (i == 0)
// 	{
// 		throw SqlException(1, "数据库查询失败", "select * from t_student");
// 	}
// }

// int main()
// {
// 	try{
// 		f1();
// 		f2();
// 	}
// 	catch (const Exception& e) // 这里捕获父类对象就可以
// 	{
// 		// 实现一个多态
// 		cout << e.what() << endl;
// 	}
// 	catch (...)
// 	{
// 		cout << "Unkown Exception" << endl;
// 	}

// 	return 0;
// }

// #include <iostream>

// using namespace std;

// double Division(int a, int b)
// {
//     //当b == 0时抛出异常
//     if(b == 0)
//     {
//         throw "Division by zero condition!";
//     }
//     else 
//     {
//         return ((double)a / (double)b);
//     }
// }

// void Func()
// {
//     int len, time;
//     cin >> len >> time;
//     cout << Division(len, time) << endl;
// }·

// int main()
// {
//     try {
//         Func();
//     }
//     catch (const char* errmsg)  {
//         cout << errmsg << endl;
//     }
//     return 0;
// }


// #include <iostream>
// #include <thread>
// #include <vector>
// #include <mutex>
// #include <condition_variable>
// #include <atomic>

// using namespace std;

// int main()
// {
//     int i = 0;
//     thread t1([&i](){
//         while(i < 10)
//         {
//             cout << "Thread 1 coming!" << endl;
//             i++;
//         }  
//     });
//     cout << t1.get_id() << endl;
//     t1.join();
//     return 0;
// }

// int main()
// {
//     mutex mtx;  //保护下面的条件变量
//     condition_variable cv;
//     bool flag = true;
//     //打印奇数
//     int i = 1;
//     thread t1([&i, &mtx, &cv, &flag](){
//         while(i < 100)
//         {
//             {
//                 std::unique_lock<mutex> lock(mtx);
//                 cv.wait(lock, [&flag](){return flag; });
//                 cout << this_thread::get_id() << " : " << i << endl;
//                 i += 2;
//                 flag = false;
//                 cv.notify_one();
//             }
//         }
//     });
//     //打印偶数
//     int j = 2;
//     thread t2([&j, &mtx, &cv, &flag](){
//         while(j < 100)
//         {
//             {
//                 std::unique_lock<mutex> lock(mtx);
//                 cv.wait(lock, [&flag](){return !flag; });
//                 cout << this_thread::get_id() << " : " << j << endl;
//                 j += 2;
//                 flag = true;
//                 cv.notify_one();
//             }
//         }
//     });

//     t1.join();
//     t2.join();

//     return 0;
// }

// #include <iostream>
// #include <vector>
// #include <mutex>
// #include <condition_variable>
// #include <atomic>

// using namespace std;

// int main()
// {
//     int n = 2;  // thread num
//     vector<thread> works(n);
//     mutex mtx;
//     for(auto &thd: works)
//     {
//         thd = thread([&mtx]{
//             for(int i = 0; i < 100; i++)
//             {
//                 mtx.lock();
//                 cout << this_thread::get_id() << endl;
//                 mtx.unlock();
//             }
//         });
//     }
    
//     return 0;
// }

